package com.easylinkin.linkappapi.powerdistribution.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.easylinkin.linkappapi.common.exceptions.BusinessException;
import com.easylinkin.linkappapi.common.service.CommonService;
import com.easylinkin.linkappapi.powerdistribution.entity.DistributionCabinetConfiguration;
import com.easylinkin.linkappapi.powerdistribution.entity.DistributionCabinetConfigurationExpression;
import com.easylinkin.linkappapi.powerdistribution.entity.DistributionCabinetTypeSite;
import com.easylinkin.linkappapi.powerdistribution.mapper.DistributionCabinetConfigurationMapper;
import com.easylinkin.linkappapi.powerdistribution.mapper.DistributionCabinetTypeSiteMapper;
import com.easylinkin.linkappapi.powerdistribution.service.DistributionCabinetConfigurationExpressionService;
import com.easylinkin.linkappapi.powerdistribution.service.DistributionCabinetConfigurationService;
import com.easylinkin.linkappapi.powerdistribution.service.DistributionCabinetTypeSiteService;
import com.easylinkin.linkappapi.security.context.LinkappUserContextProducer;
import com.easylinkin.linkappapi.security.entity.LinkappUser;
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

/**
 * <p>
 * 配电柜类型组态 服务实现类
 * </p>
 *
 * @author TongJie
 * @since 2020-08-05
 */
@Service
public class DistributionCabinetConfigurationServiceImpl extends ServiceImpl<DistributionCabinetConfigurationMapper, DistributionCabinetConfiguration> implements DistributionCabinetConfigurationService {

    private static final Logger LOGGER = LoggerFactory.getLogger(DistributionCabinetConfigurationServiceImpl.class);

    @Resource
    private CommonService commonService;
    @Resource
    private LinkappUserContextProducer linkappUserContextProducer;
    @Resource
    private DistributionCabinetConfigurationExpressionService distributionCabinetConfigurationExpressionService;
    @Resource
    private DistributionCabinetTypeSiteMapper distributionCabinetTypeSiteMapper;
    @Resource
    private DistributionCabinetTypeSiteService distributionCabinetTypeSiteService;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(DistributionCabinetConfiguration distributionCabinetConfiguration) {
        LinkappUser user = linkappUserContextProducer.getCurrent();
        distributionCabinetConfiguration.setTenantId(user.getTenantId());
        commonService.setCreateAndModifyInfo(distributionCabinetConfiguration);

        validParamRequired(distributionCabinetConfiguration);
        validParamFormat(distributionCabinetConfiguration);
        validRepeat(distributionCabinetConfiguration);

        save(distributionCabinetConfiguration);

        List<DistributionCabinetConfigurationExpression> distributionCabinetConfigurationExpressions = distributionCabinetConfiguration.getDistributionCabinetConfigurationExpressions();

        Assert.notEmpty(distributionCabinetConfigurationExpressions, "组态表达式不能为空");

        distributionCabinetConfigurationExpressions.forEach(distributionCabinetConfigurationExpression -> {
            distributionCabinetConfigurationExpression.setDistributionCabinetConfigurationId(distributionCabinetConfiguration.getId());
            distributionCabinetConfigurationExpressionService.add(distributionCabinetConfigurationExpression);
        });

        autoAdjustCabinetConfigurationGroupNumberSort(distributionCabinetConfiguration.getDistributionCabinetTypeSiteId());
    }

    /**
     * 自动调整 配电组态的 group_number 的 顺序
     */
    private void autoAdjustCabinetConfigurationGroupNumberSort(String distributionCabinetConfigurationSiteId) {
        Assert.hasLength(distributionCabinetConfigurationSiteId, "distributionCabinetTypeSiteId 为空");

        DistributionCabinetTypeSite distributionCabinetTypeSite = distributionCabinetTypeSiteService.getById(distributionCabinetConfigurationSiteId);
        if (distributionCabinetTypeSite == null || ObjectUtils.isEmpty(distributionCabinetTypeSite.getDistributionCabinetTypeId())) {
            return;
        }
        QueryWrapper<DistributionCabinetTypeSite> qw = new QueryWrapper<>();
        qw.in("distribution_cabinet_type_id", distributionCabinetTypeSite.getDistributionCabinetTypeId());
        qw.select("id");
        List<DistributionCabinetTypeSite> distributionCabinetTypeSites = distributionCabinetTypeSiteMapper.selectList(qw);
        List<String> distributionCabinetTypeSitesIds = distributionCabinetTypeSites.stream().map(DistributionCabinetTypeSite::getId).collect(Collectors.toList());

        QueryWrapper<DistributionCabinetConfiguration> qw2 = new QueryWrapper<>();
        qw2.in("distribution_cabinet_type_site_id", distributionCabinetTypeSitesIds);
        qw2.orderByAsc("create_time");

        List<DistributionCabinetConfiguration> distributionCabinetConfigurations = list(qw2);

        for (int i = 0; i < distributionCabinetConfigurations.size(); i++) {
            DistributionCabinetConfiguration configuration = distributionCabinetConfigurations.get(i);
            if (!Integer.valueOf(i).equals(configuration.getGroupNumber())) {
                configuration.setGroupNumber(i);
                updateById(configuration);
            }
        }
    }


    /**
     * 校验重复
     */
    private void validRepeat(DistributionCabinetConfiguration distributionCabinetConfiguration) {
        QueryWrapper<DistributionCabinetConfiguration> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", distributionCabinetConfiguration.getName());
        queryWrapper.eq("distribution_cabinet_type_site_id", distributionCabinetConfiguration.getDistributionCabinetTypeSiteId());
        List<DistributionCabinetConfiguration> list = baseMapper.selectList(queryWrapper);
        if (list.size() == 0) {
            return;
        }
        if (list.size() > 1) {
            throw new BusinessException("组态名称有重复");
        }
        if (StringUtils.isEmpty(distributionCabinetConfiguration.getId())) {
            throw new BusinessException("组态名称已存在");
        }
        if (!distributionCabinetConfiguration.getId().equals(list.get(0).getId())) {
            throw new BusinessException("组态名称已存在");
        }
        
    }


    /**
     * 校验参数必填
     */
    private void validParamRequired(DistributionCabinetConfiguration distributionCabinetConfiguration) {
        Assert.notNull(distributionCabinetConfiguration, "参数为空");
        Assert.isTrue(StringUtils.isNotBlank(distributionCabinetConfiguration.getName()), "名称为空");
        Assert.isTrue(StringUtils.isNotBlank(distributionCabinetConfiguration.getStatusPicture()), "getStatusPicture 为空");
        Assert.isTrue(StringUtils.isNotBlank(distributionCabinetConfiguration.getTenantId()), "getTenantId 为空");
        Assert.hasLength(distributionCabinetConfiguration.getDistributionCabinetTypeSiteId(), "getDistributionCabinetTypeSiteId为空");

    }

    /**
     * 校验参数格式
     */
    private void validParamFormat(DistributionCabinetConfiguration distributionCabinetConfiguration) {
        Assert.isTrue(distributionCabinetConfiguration.getName() == null || distributionCabinetConfiguration.getName().length() <= 32, "名称超长");
        Assert.isTrue(distributionCabinetConfiguration.getDescription() == null || distributionCabinetConfiguration.getDescription().length() <= 255, "组态描述超长");
        Assert.isTrue(distributionCabinetConfiguration.getTenantId() == null || distributionCabinetConfiguration.getTenantId().length() <= 32, "租户id超长");
        Assert.isTrue(distributionCabinetConfiguration.getDistributionCabinetTypeSiteId() == null || distributionCabinetConfiguration.getDistributionCabinetTypeSiteId().length() <= 32, "getDistributionCabinetTypeSiteId超长");
    }

    @Override
    public List<DistributionCabinetConfiguration> getDistributionCabinetConfigurations(DistributionCabinetConfiguration distributionCabinetConfiguration) {
        distributionCabinetConfiguration.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
        return baseMapper.getDistributionCabinetConfigurations(distributionCabinetConfiguration);
    }

    @Override
    public List<DistributionCabinetConfiguration> getDistributionCabinetConfigurationWithExpressions(DistributionCabinetConfiguration distributionCabinetConfiguration) {
        distributionCabinetConfiguration.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
        return baseMapper.getDistributionCabinetConfigurationWithExpressions(distributionCabinetConfiguration);
    }

    @Override
    public IPage<DistributionCabinetConfiguration> getDistributionCabinetConfigurations(Page page, DistributionCabinetConfiguration distributionCabinetConfiguration) {
        distributionCabinetConfiguration.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
        return baseMapper.getDistributionCabinetConfigurations(page, distributionCabinetConfiguration);
    }

    @Override
    public DistributionCabinetConfiguration getDistributionCabinetConfiguration(String id) {
        return baseMapper.getDistributionCabinetConfiguration(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateDistributionCabinetConfiguration(DistributionCabinetConfiguration distributionCabinetConfiguration) {
        Assert.notNull(distributionCabinetConfiguration, "参数为空");
        DistributionCabinetConfiguration originDistributionCabinetConfiguration = getById(distributionCabinetConfiguration.getId());
        Assert.notNull(originDistributionCabinetConfiguration, "原组态不存在");
        Assert.hasLength(distributionCabinetConfiguration.getDistributionCabinetTypeSiteId(), "getDistributionCabinetTypeSiteId 为空");

        //        忽略 组编号，前端不用传，如果传了值 直接忽略，
        distributionCabinetConfiguration.setGroupNumber(null);

        validRepeat(distributionCabinetConfiguration);
        validParamFormat(distributionCabinetConfiguration);
        commonService.setModifyInfo(distributionCabinetConfiguration);
        updateById(distributionCabinetConfiguration);
//        删除以前关联的表达式
        QueryWrapper<DistributionCabinetConfigurationExpression> qw = new QueryWrapper<>();
        qw.eq("distribution_cabinet_configuration_id", distributionCabinetConfiguration.getId());
        distributionCabinetConfigurationExpressionService.remove(qw);
// 新增新的表达式关联
        List<DistributionCabinetConfigurationExpression> distributionCabinetConfigurationExpressions = distributionCabinetConfiguration.getDistributionCabinetConfigurationExpressions();
        Assert.notEmpty(distributionCabinetConfigurationExpressions, "组态表达式不能为空");
        distributionCabinetConfigurationExpressions.forEach(distributionCabinetConfigurationExpression -> {
            distributionCabinetConfigurationExpression.setDistributionCabinetConfigurationId(distributionCabinetConfiguration.getId());
            distributionCabinetConfigurationExpressionService.add(distributionCabinetConfigurationExpression);
        });
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteBatch(List<DistributionCabinetConfiguration> distributionCabinetConfigurationList) {
        Assert.notEmpty(distributionCabinetConfigurationList, "参数为空");
        List<String> ids = distributionCabinetConfigurationList.stream().map(DistributionCabinetConfiguration::getId).collect(Collectors.toList());
        if (ObjectUtils.isEmpty(ids)) {
            return;
        }
//        批量删除的肯定都是在同一类型 DistributionCabinetType 之下的
        DistributionCabinetConfiguration distributionCabinetConfigurationOne = getById(ids.get(0));
        Assert.notNull(distributionCabinetConfigurationOne, ids.get(0) + "数据已被删除");
        String distributionCabinetTypeSiteId = distributionCabinetConfigurationOne.getDistributionCabinetTypeSiteId();

        //        删除以前关联的表达式
        QueryWrapper<DistributionCabinetConfigurationExpression> qw = new QueryWrapper<>();
        qw.in("distribution_cabinet_configuration_id", ids);
        distributionCabinetConfigurationExpressionService.remove(qw);
//        删除组态
        removeByIds(ids);
//        重新调整组顺序
        autoAdjustCabinetConfigurationGroupNumberSort(distributionCabinetTypeSiteId);
    }


    @Override
    public void flashOldGroupNumberSortDataGlobal() {
        QueryWrapper<DistributionCabinetTypeSite> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("distinct id");
        List<DistributionCabinetTypeSite> distributionCabinetTypeSiteList = distributionCabinetTypeSiteMapper.selectList(queryWrapper);
        for (DistributionCabinetTypeSite distributionCabinetTypeSite : distributionCabinetTypeSiteList) {
            autoAdjustCabinetConfigurationGroupNumberSort(distributionCabinetTypeSite.getId());
        }
    }
}
